package middleware

import (
	"github.com/Sir-yuChen/funAnalyse/global"
	"github.com/Sir-yuChen/funAnalyse/model"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"os"
	"strconv"
	"time"
)

func CheckApiResourcesMiddleware(api *model.StockApiResource) gin.HandlerFunc {
	//初始化加载路径时检查DB中是否存在路由信息
	var apiResourceId int
	var mo model.StockApiResource
	// 注意 当数据口接口状态和代码中的状态不一致 抛出警告通知，以DB信息为主
	err := global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		err := tx.Model(model.StockApiResource{}).Where("api_name = ? And api_path = ? And api_type = ?",
			api.ApiName, api.ApiPath, api.ApiType).First(&mo).Error
		if err != nil && err.Error() != "record not found" {
			global.GVA_LOG.Error("初始化检查资源异常", zap.Any("StockApiResource", api))
			//os.Exit立即退出并返回给定状态
			os.Exit(0)
		}
		if mo == (model.StockApiResource{}) && err.Error() == "record not found" {
			err := tx.Model(model.StockApiResource{}).Create(&api).Error
			if err != nil {
				global.GVA_LOG.Error("初始化接口资源检查异常>>>>DB不存在资源信息,插入异常", zap.Any("StockApiResource", api))
				os.Exit(0)
			}
			apiResourceId = int(api.Id)
		}
		if mo != (model.StockApiResource{}) && (mo.Status != api.Status || mo.ResourceLeveMark != api.ResourceLeveMark) {
			api.Id = mo.Id
			apiResourceId = int(mo.Id)
			if err := tx.Model(model.StockApiResource{}).Where("id = ?", mo.Id).Updates(&api).Error; err != nil {
				global.GVA_LOG.Warn("初始化接口资源检查异常>>>>资源状态/leve不一致,更新异常", zap.Any("StockApiResource", mo), zap.String("DB_status", mo.Status), zap.String("Param_status", api.Status))
				os.Exit(0)
			}
		}
		//初始化将资源默认绑定给super用户
		var role model.StockCasbinRoleModel
		if err := tx.Model(model.StockCasbinRoleModel{}).Where(" role_name = ? And status = ? ", "super", "Y").First(&role).Error; err != nil {
			global.GVA_LOG.Error("资源加载 查询默认最高权限角色Super异常", zap.Error(err))
			return err
		}
		var total int64
		//查询是否存在绑定关系
		tx.Model(model.StockCasbinRoleRelationResourcesModel{}).Where(" role_id = ? And resource_id = ?", role.Id, mo.Id).Count(&total)
		if total <= 0 {
			now := model.LocalTime(time.Now())
			//绑定关系不存在，新增
			r := model.StockCasbinRoleRelationResourcesModel{
				RoleId:      role.Id,
				ResourceId:  apiResourceId,
				Status:      "Y",
				CreateTime:  &now,
				LastUpdTime: &now,
			}
			if err = tx.Model(model.StockCasbinRoleRelationResourcesModel{}).Create(&r).Error; err != nil {
				global.GVA_LOG.Error("资源加载,资源绑定super角色异常", zap.Any("StockApiResource", mo), zap.Error(err))
				return err
			}
			//生成规则
			if e := tx.Model(model.CasbinRuleModel{}).Create(&model.CasbinRuleModel{
				PType: "p",
				V0:    strconv.Itoa(r.RoleId),
				V1:    api.ApiPath,
				V2:    api.ApiType,
				V3:    api.Status,
			}).Error; e != nil {
				global.GVA_LOG.Error("资源加载 生成策略 异常", zap.Any("StockApiResource", mo), zap.Error(e))
				return e
			}
		}
		return nil
	})
	if err != nil {
		global.GVA_LOG.Error("资源加载异常", zap.Error(err))
		os.Exit(0)
	}
	return func(c *gin.Context) {
		// 处理请求
		c.Next()
	}
}
